Skip to content

build: add uv exclude-newer, pip uploaded-prior-to and Dependabot cooldown as supply chain guardrails#11170

Merged
julian-risch merged 7 commits intomainfrom
supply-chain-exclude-newer
Apr 30, 2026
Merged

build: add uv exclude-newer, pip uploaded-prior-to and Dependabot cooldown as supply chain guardrails#11170
julian-risch merged 7 commits intomainfrom
supply-chain-exclude-newer

Conversation

@julian-risch
Copy link
Copy Markdown
Member

@julian-risch julian-risch commented Apr 22, 2026

Related Issues

Supply chain attacks increasingly target the window between a package being compromised and defenders noticing. A 24-hour age requirement means that even if a dependency is compromised and a malicious version is published, it won't automatically land in a uv lock run or a Dependabot PR within that window.

Changes

Hardens the haystack-ai package against supply chain attacks by introducing three complementary dependency age guardrails.

pyproject.toml — uv exclude-newer guardrail:

  • Adds exclude-newer = "24 hours" under [tool.uv], which tells uv to ignore any package version published within the last 24 hours during resolution. This prevents a freshly-compromised or typosquatted package version from being picked up at install/lock time.
  • Adds exclude-newer-package exemptions for first-party packages (haystack-experimental, haystack-pydoc-tools) so freshly-published releases of our own packages are always resolvable.
  • The duration is evaluated relative to the current clock at uv lock / uv sync time — no manual date updates needed. See uv dependency cooldowns docs for details.

.github/dependabot.yml — Dependabot cooldown:

  • Adds a pip ecosystem entry so Dependabot tracks Python dependencies.
  • Adds cooldown.default-days: 1 to both pip and github-actions entries, so Dependabot won't open bump PRs for versions published less than 1 day ago — matching the uv window.

--uploaded-prior-to — pip guardrail:
Add --uploaded-prior-to P1D to all pip install commands in CI workflows (pip 26.1+), so packages uploaded within the last 24 hours are skipped at install time. I had to upgrade pip in CI, otherwise the relative duration won't be picked up correctly because that was only introduced in pip 26.1

How did you test it?

Upgraded uv and hatch and pip locally. Confirmed that the added parameter has the effect that more recent releases are not installed.

No functional code changes. This only affects dependency resolution behavior.

Notes for the reviewer

I added a release note mentioning the changes to pyproject.toml only because that's the only change that directly affects users. Does that sound good to you?

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • I have updated the related issue with new insights and changes.
  • I have added unit tests and updated the docstrings.
  • I've used one of the conventional commit types for my PR title: fix:, feat:, build:, chore:, ci:, docs:, style:, refactor:, perf:, test: and added ! in case the PR includes breaking changes.
  • I have documented my code.
  • I have added a release note file, following the contributors guidelines.
  • I have run pre-commit hooks and fixed any issue.

🤖 Generated with Claude Code

…uardrails

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
haystack-docs Ignored Ignored Preview Apr 30, 2026 9:21am

Request Review

Comment thread pyproject.toml
@coveralls
Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 24773716980

Coverage increased (+0.01%) to 92.857%

Details

  • Coverage increased (+0.01%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 17177
Covered Lines: 15950
Line Coverage: 92.86%
Coverage Strength: 0.93 hits per line

💛 - Coveralls

Extends the supply chain hardening by passing --uploaded-prior-to P1D
(pip 26.1 relative duration format) to every pip install <packages>
command across CI workflows, so packages published within the last 24
hours are excluded at install time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@julian-risch
Copy link
Copy Markdown
Member Author

pip 26.0 introduced --uploaded-prior-to and with pip 26.1 it now accepts a duration in days (relative). https://pip.pypa.io/en/latest/user_guide/#filtering-by-upload-time
I added this in another commit.

julian-risch and others added 2 commits April 30, 2026 08:51
pip 26.1 requires the value to be joined with = rather than a space
for the relative duration format to be parsed correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
P1D relative duration requires pip>=26.1 (latest as of this commit).
CI runners ship with older pip, so each install step now upgrades pip
first to ensure the flag is recognised.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@julian-risch julian-risch changed the title chore: add uv exclude-newer and Dependabot cooldown as supply chain guardrails chore: add uv exclude-newer, pip uploaded-prior-to and Dependabot cooldown as supply chain guardrails Apr 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

Coverage report

This PR does not seem to contain any modification to coverable code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@julian-risch julian-risch changed the title chore: add uv exclude-newer, pip uploaded-prior-to and Dependabot cooldown as supply chain guardrails build: add uv exclude-newer, pip uploaded-prior-to and Dependabot cooldown as supply chain guardrails Apr 30, 2026
@julian-risch julian-risch marked this pull request as ready for review April 30, 2026 07:10
@julian-risch julian-risch requested a review from a team as a code owner April 30, 2026 07:10
@julian-risch julian-risch requested review from anakin87 and bogdankostic and removed request for a team and bogdankostic April 30, 2026 07:10
Comment on lines +1 to +9
---
security:
- |
Haystack's uv configuration now excludes packages published within the last
24 hours when resolving dependencies, reducing exposure to supply chain
attacks via freshly compromised packages. If you need to install a dependency
that was published less than 24 hours ago, you can override this by running
``uv sync --exclude-newer="0 days"`` or
``uv pip install <package> --exclude-newer="0 days"``.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that this is relevant for users. Or at least, only for those who install from main.
WDYT?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry let me check better

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say that a user doing pip install haystack-ai would still install the latest version of dependencies. So I'd remove the release note.

Is my interpretation correct?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pip install haystack-ai would still install the latest version of dependencies, correct. I am fine with removing the release note. 👍

Comment thread .github/workflows/project.yml Outdated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude Bot commented Apr 30, 2026

Code review

Issue: Supply chain gap — pip upgrade is not subject to the cooling-off window

Every job modified in this PR upgrades pip before the --uploaded-prior-to=P1D guard is active:

# .github/workflows/tests.yml (and 12 other workflow files)
python -m pip install --upgrade pip          # ← unguarded
pip install hatch==${{ env.HATCH_VERSION }} --uploaded-prior-to=P1D

If an attacker publishes a malicious pip release within the last 24 hours, the compromised pip is installed by the first line — and then handles all subsequent pip install calls, including those with --uploaded-prior-to. This undermines the exact threat model the PR is designed to address, and is most consequential in the release workflows (pypi_release.yml, nightly_testpypi_release.yml, release.yml, github_release.yml) where pip runs in the same job that publishes haystack-ai to PyPI.

See:

- name: Install Hatch
run: |
python -m pip install --upgrade pip

Suggested fix: Add --uploaded-prior-to=P1D to the upgrade step itself. The pip bundled with actions/setup-python on current GitHub-hosted runners supports this flag:

python -m pip install --upgrade pip --uploaded-prior-to=P1D
pip install hatch==${{ env.HATCH_VERSION }} --uploaded-prior-to=P1D

This pattern should be applied consistently across all 13 modified workflow files.


Checked for bugs and CLAUDE.md compliance. No other issues found.

@julian-risch
Copy link
Copy Markdown
Member Author

Code review

Issue: Supply chain gap — pip upgrade is not subject to the cooling-off window

I considered this even before this automated code review. However, most recent pip version is required BEFORE we use the uploaded-prior-to parameter. That's why I won't change anything to address this comment.

Copy link
Copy Markdown
Member

@anakin87 anakin87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove the release note.

Then feel free to merge.

Thank you!

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@julian-risch julian-risch enabled auto-merge (squash) April 30, 2026 09:22
@julian-risch julian-risch added the ignore-for-release-notes PRs with this flag won't be included in the release notes. label Apr 30, 2026
@julian-risch julian-risch merged commit 8887691 into main Apr 30, 2026
30 of 31 checks passed
@julian-risch julian-risch deleted the supply-chain-exclude-newer branch April 30, 2026 11:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ignore-for-release-notes PRs with this flag won't be included in the release notes. topic:build/distribution topic:CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants